﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ImageK.Java
{
    public class Arrays
    {
        /**
         * Copies the specified array, truncating or padding with zeros (if necessary)
         * so the copy has the specified length.  For all indices that are
         * valid in both the original array and the copy, the two arrays will
         * contain identical values.  For any indices that are valid in the
         * copy but not the original, the copy will contain {@code 0}.
         * Such indices will exist if and only if the specified length
         * is greater than that of the original array.
         *
         * @param original the array to be copied
         * @param newLength the length of the copy to be returned
         * @return a copy of the original array, truncated or padded with zeros
         *     to obtain the specified length
         * @throws NegativeArraySizeException if {@code newLength} is negative
         * @throws NullPointerException if {@code original} is null
         * @since 1.6
         */
        public static int[] copyOf(int[] original, int newLength)
        {
            int[] copy = new int[newLength];
            Array.Copy(original, 0, copy, 0,
                Math.Min(original.Length, newLength));
            return copy;
        }

        public static bool Equals<T>(T[] array1, T[] array2)
        {
            if (array1 == array2) return true;
            if (array1 == null || array2 == null) return false;
            if (array1.Length != array1.Length) return false;
            Type equatable = typeof(T).GetInterface("IEquatable`1");
            if (equatable != null)
            {
                MethodInfo equalMethod = equatable.GetMethod("Equals", BindingFlags.Instance | BindingFlags.Public);
                for (int i = 0; i < array1.Length; i++)
                {
                    if (!(bool)equalMethod.Invoke(array1[i], new object[] { array2[i] })) return false;
                }
                return true;
            }
            Type comparable = typeof(T).GetInterface("IComparable`1");
            if (comparable != null)
            {
                MethodInfo compareMethod = comparable.GetMethod("CompareTo", BindingFlags.Instance | BindingFlags.Public);
                for (int i = 0; i < array1.Length; i++)
                {
                    if (!(bool)compareMethod.Invoke(array1[i], new object[] { array2[i] })) return false;
                }
                return true;
            }
            for (int i = 0; i < array1.Length; i++)
            {
                if (!array1[i].Equals(array2[i])) return false;
            }
            return true;
        }
    }
}
